package com.jhj.service.bm.impl;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.jhj.po.bm.model.Sale;
import com.jhj.po.bm.model.SaleStat;
import com.jhj.vo.bm.OrderSearchVo;
import com.jhj.service.bm.BmOrderService;
import com.jhj.service.bm.SaleService;
import com.jhj.service.bm.SaleStatService;
import com.jhj.service.impl.BaseServiceImpl;
import com.jhj.utils.DateUtil;
import com.jhj.utils.MathBigDecimalUtil;
import com.jhj.utils.TimeStampUtil;



@Service
public class SaleStatServiceImpl extends BaseServiceImpl<SaleStat> implements SaleStatService {
	
	@Autowired
	private BmOrderService orderService;
	
	@Autowired
	private SaleService saleService;
	
	/**
	 * 统计销售老师的订单情况，
	 * totalOrder = total = 总订单数
	 * totalProcess = 正在进行的订单数， 持有订单数
	 * totalDone = 签约订单数
	 * totalClose = 关闭订单数.
	 */
	@SuppressWarnings("unlikely-arg-type")
	@Override
	public void saleStat() {
		//1. 获取全部时间的订单数统计
		OrderSearchVo orderVo = new OrderSearchVo();
		List<Map<Integer, Integer>> countSaleList = orderService.countOrderSale(orderVo);
		
		//2. 获取最近30天的订单数统计
		orderVo = new OrderSearchVo();
		String nowDateStr = DateUtil.getToday();
		Date nowDate = DateUtil.parse(nowDateStr);
		String oneMonthDayStr = DateUtil.addDay(nowDate, -1, Calendar.MONTH, DateUtil.DEFAULT_PATTERN);
		
		Long startTime = TimeStampUtil.getMillisOfDayFull(oneMonthDayStr + " 23:59:59")/1000;
		Long endTime = TimeStampUtil.getNow();
		orderVo.setStartTime(startTime.intValue());
		orderVo.setEndTime(endTime.intValue());
		List<Map<Integer, Integer>> countSaleList30 = orderService.countOrderSale(orderVo);
		
		
		Sale saleSearchVo = new Sale();
		List<Sale> sales = saleService.selectBySearchVo(saleSearchVo, "sale_id desc");
		
		int len = sales.size();
		int countLen = countSaleList.size();
		for (int i = 0; i < len; i++) {
			Sale sale = sales.get(i);
			
			Integer saleId = sale.getSaleId();
			Integer total = 0;
			Integer totalProcess = 0;
			Integer totalDone = 0;
			Integer totalClose = 0;
			
			//转化率
			BigDecimal changeRatio = new BigDecimal(0);
			
			for (int j = 0; j < countLen; j++) {
				Map<Integer, Integer> item = countSaleList.get(j);
				
				Integer countSaleId = item.get("saleId");
				if (!saleId.equals(countSaleId)) continue;
				
				total = ( (Number)item.get("total") ).intValue();
				totalProcess = ( (Number)item.get("totalProcess") ).intValue();
				totalDone = ( (Number)item.get("totalDone") ).intValue(); 
				totalClose = ( (Number)item.get("totalClose") ).intValue(); 
				
			}
			
			SaleStat count30 = this.mathChangeRatio(saleId, countSaleList30);
			changeRatio = count30.getChangeRatio();
			
			SaleStat record = this.selectByPrimaryKey(saleId);
			Boolean isnew = false;
			if (record == null) {
				record = this.initPo(new SaleStat());
				isnew = true;
			}
			
			record.setSaleId(saleId);
			record.setSaleStatus(sale.getStatus());
			record.setTotalOrder(total);
			record.setTotalProcess(totalProcess);
			record.setTotalDone(totalDone);
			record.setTotalClose(totalClose);
			record.setChangeRatio(changeRatio);
			
			
			if (isnew == true) {
				
				record.setAddTime(TimeStampUtil.getNowSecond().intValue());
				record.setUpdateTime(TimeStampUtil.getNowSecond().intValue());
				this.insert(record);
			} else {
				record.setUpdateTime(TimeStampUtil.getNowSecond().intValue());
				this.update(record);
			}
		}
	}
	
	/**
	 * 计算最近30天的转化率
	 * @param saleId
	 * @param countSaleList30
	 * @return
	 */
	@SuppressWarnings("unlikely-arg-type")
	private SaleStat mathChangeRatio(Integer saleId, List<Map<Integer, Integer>> countSaleList30) {
		SaleStat saleStat = new SaleStat();
		Integer total = 0;
		Integer totalProcess = 0;
		Integer totalDone = 0;
		Integer totalClose = 0;
		
		int len = countSaleList30.size();
		for (int i = 0; i < len; i++) {
			Map<Integer, Integer> item = countSaleList30.get(i);
			
			Integer countSaleId = item.get("saleId");
			if (!saleId.equals(countSaleId)) continue;
			
			total = ( (Number)item.get("total") ).intValue();
			totalProcess = ( (Number)item.get("totalProcess") ).intValue();
			totalDone = ( (Number)item.get("totalDone") ).intValue(); 
			totalClose = ( (Number)item.get("totalClose") ).intValue(); 
			
		}
		
		//转化率
		BigDecimal changeRatio = new BigDecimal(0);
		if (total > 0) {
			changeRatio = MathBigDecimalUtil.div(new BigDecimal(totalProcess), new BigDecimal(total));
			changeRatio = MathBigDecimalUtil.round(changeRatio, 2);
		}
		saleStat.setSaleId(saleId);
		saleStat.setTotalOrder(total);
		saleStat.setTotalProcess(totalProcess);
		saleStat.setTotalDone(totalDone);
		saleStat.setTotalClose(totalClose);
		saleStat.setChangeRatio(changeRatio);
		return saleStat;
	}
	
	/**
	 * 派工逻辑
	 * 	1、保姆订单派发按照俄罗斯轮盘规则进行分配；（按照单品类轮转）
		2、新增销售派单上线饱和值为50个，超过50个开始计算转化率；
		3、订单转化率低于10%停止派单；（最近30天的转化率）
		4、转化率=签约订单/（关闭订单+签约订单+持有订单）*100%；
		5、派单针对门店派发，不针对单独某个销售老师；
		6、有效时效为30分钟，超过30分钟没响应按照规则1分配给下一个门店；
		新增门店管理项目，销售老师归属所属门店；
		
		其他规定：
		1、取消销售等级划分；
		2、取消原有派单规则；
		3、在12月15日前让现有谈单老师清理本账户订单信息，将剩余订单信息计算出前30天转
		化率作为始点，参照最新派单规则实施派单；
		4、销售取消人工关闭；
		5、新增加门店排在俄罗斯轮盘首位；
	 */
	@Override
	public HashMap<String, Object> orderDispatch() {
		HashMap<String, Object> dispatchInfo = new HashMap<String, Object>();
		
		//1.进行老师的数据统计工作.
		this.saleStat();
		
		SaleStat searchVo = new SaleStat();
		List<SaleStat> list = this.selectBySearchVo(searchVo, "sale_id desc");
		
		//2.找出最近一次匹配的老师.
		//lastStatus1 = 最近一次派单的老师
		//lastStatus2 = 最近一次接单的老师
		int lastStatus = -1;
		
		int len = list.size();
		for (int i = 0; i < len; i++) {
			SaleStat item = list.get(i);
			Integer saleStatus = item.getSaleStatus();
			//排除离职，请假的老师.
			if (!saleStatus.equals(1)) continue;
			
			Integer status = item.getStatus();
			if (status.equals(1)) {
				lastStatus = i;
			}
			
		}
		Integer nextMatch  = 0;
		String dispatchBy = "正常派单轮转.";
		if (lastStatus >= 0) {
			nextMatch = lastStatus +1;
			if (nextMatch >= len) nextMatch = 0;
		}
		
		//3.获取当前的老师统计信息，如果当前老师的持有订单数大于50，还需要判断是否转化率小于10;
		Integer matchSaleId = 0;
		Integer loop = 0;
		while (true) {
			if (loop >= len) break;
			if (nextMatch >= len) nextMatch = 0;
			SaleStat saleStat = list.get(nextMatch);
			if (saleStat.getSaleStatus().equals(1)) {
				matchSaleId = saleStat.getSaleId();
				break;
			}
			nextMatch++;
			loop++;
		}
		
		
		
//		Boolean matchOverOrderCount = this.mathMaxTotalProcess(saleStat);
//		
//		//如果当前轮换的老师，不满足转化率小于10的情况，则需要轮转到下一位老师.
//		if (matchOverOrderCount == false) {
//			Integer loop = 0;
//			while(true) {
//				if (loop >= len) break;
//				nextMatch = nextMatch + 1;
//				if (nextMatch >= len) nextMatch = 0;
//				SaleStat loopSaleStat = list.get(nextMatch);
//				Integer loopMatchSaleId = loopSaleStat.getSaleId();
//				if (loopMatchSaleId.equals(matchSaleId)) break;
//				
//				matchOverOrderCount = this.mathMaxTotalProcess(loopSaleStat);
//				if (matchOverOrderCount == true) break;
//				loop++;
//			}
//			
//			 saleStat = list.get(nextMatch);
//			 matchSaleId = saleStat.getSaleId();
//			 
//			 dispatchBy = "转化率派工";
//		}
		
		dispatchInfo.put("orderDispatch", 0);
		dispatchInfo.put("saleId", matchSaleId);
		dispatchInfo.put("dispatchBy", dispatchBy);
		return dispatchInfo;
	}
	
	/**
	 * 讲saleStat全部stauts = 0
	 * 然后设置特定的saleID  status = 1;
	 * @param saleId
	 */
	@Override
	public void setDispatchStatus(Integer saleId) {
		SaleStat searchVo = new SaleStat();
		List<SaleStat> list = this.selectBySearchVo(searchVo, "sale_id desc");
		
		int len = list.size();
		for (int i = 0 ; i < len; i++) {
			SaleStat item = list.get(i);
			Integer itemSaleId = item.getSaleId();
			SaleStat record = new SaleStat();
			record.setSaleId(itemSaleId);
			record.setStatus(0);
			record.setUpdateTime(TimeStampUtil.getNowSecond().intValue());
			this.update(record);
		}
		
		SaleStat saleStat = new SaleStat();
		saleStat.setSaleId(saleId);
		saleStat.setStatus(1);
		saleStat.setUpdateTime(TimeStampUtil.getNowSecond().intValue());
		this.update(saleStat);
	}
	
	/**
	 * 如果当前老师的持有订单数大于50，还需要判断是否转化率小于10;
	 * 返回值
	 * true == 满足持有订单数小于50 或者 转化率大于10%
	 * false  == 不满足
	 */
	private boolean mathMaxTotalProcess(SaleStat saleStat) {
		
		//排除离职，请假的老师.
		Integer saleStatus = saleStat.getSaleStatus();
		if (!saleStatus.equals(1)) return false;
		
		
		Integer totalProcess = saleStat.getTotalProcess();
		BigDecimal changeRatio = saleStat.getChangeRatio();
		
		//如果持有订单数大于50
		if (totalProcess > 50) {
			BigDecimal minChangeRatio = new BigDecimal(0.1);
			if (changeRatio.compareTo(minChangeRatio) < 0) {
				return false;
			}
		}
		
		return true;
	}
}
